package com.ht.modules.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ht.entity.DictModel;
import com.ht.entity.DictModelMany;
import com.ht.utils.ChinesePinyinUtil;
import org.apache.logging.log4j.util.Strings;
import com.ht.modules.system.entity.SysDict;
import com.ht.modules.system.entity.SysDictItem;
import com.ht.modules.system.mapper.SysDictItemMapper;
import com.ht.modules.system.mapper.SysDictMapper;
import com.ht.modules.system.service.ISysDictItemService;
import com.ht.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;

/**
 * 字典表 服务实现类
 */
@Service
@Slf4j
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements ISysDictService {

    @Autowired
    private SysDictMapper sysDictMapper;
    @Autowired
    private SysDictItemMapper sysDictItemMapper;
    @Autowired
    @Lazy
    private ISysDictItemService sysDictItemService;

    /**
     * 通过查询指定code 获取字典
     */
    @Override
    @Cacheable(value = "dictCache", key = "#code")
    public List<DictModel> queryDictItemsByCode(String code) {
        log.info("无缓存dictCache的时候调用这里！");
        return sysDictMapper.queryDictItemsByCode(code);
    }

    /**
     * 通过查询指定code 获取字典值text
     */
    @Override
    @Cacheable(value = "dictCache")
    public String queryDictTextByKey(String code, String key) {
        log.info("无缓存dictText的时候调用这里！");
        return sysDictMapper.queryDictTextByKey(code, key);
    }

    /**
     * 通过查询指定table的 text code 获取字典
     * dictTableCache采用redis缓存有效期10分钟
     */
    @Override
    public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
        log.info("无缓存dictTableList的时候调用这里！");
        return sysDictMapper.queryTableDictItemsByCode(table, text, code);
    }

    /**
     * 通过查询指定table的 text code 获取字典值text
     * dictTableCache采用redis缓存有效期10分钟
     */
    @Override
    @Cacheable(value = "dictTableCache")
    public String queryTableDictTextByKey(String table, String text, String code, String key) {
        log.info("无缓存dictTable的时候调用这里！");
        return sysDictMapper.queryTableDictTextByKey(table, text, code, key);
    }

    /**
     * 根据字典类型id删除关联表中其对应的数据
     */
    @Override
    public boolean deleteByDictId(SysDict sysDict) {
        sysDict.setDelFlag(2);
        return this.updateById(sysDict);
    }

    @Override
    @Transactional
    public void saveMain(SysDict sysDict, List<SysDictItem> sysDictItemList) {

        sysDictMapper.insert(sysDict);
        if (sysDictItemList != null) {
            for (SysDictItem entity : sysDictItemList) {
                entity.setDictId(sysDict.getId());
                sysDictItemMapper.insert(entity);
            }
        }
    }

    @Override
    public List<DictModel> queryAllDepartBackDictModel() {
        return baseMapper.queryAllDepartBackDictModel();
    }

    @Override
    public List<DictModel> queryAllUserBackDictModel() {
        return baseMapper.queryAllUserBackDictModel();
    }

    @Override
    public List<DictModel> queryTableDictItems(String table, String text, String code, String keyword) {
        return baseMapper.queryTableDictItems(table, text, code, "%" + keyword + "%");
    }

    @Override
    public List<Map> getCommonList(String table, String columns, String whereSql, String joinSql) {
        return sysDictMapper.getCommonList(table, columns, whereSql, joinSql);

    }

    @Override
    public Map<String, List<DictModel>> queryManyDictByKeys(List<String> dictCodeList, List<String> keys) {
        List<DictModelMany> list = sysDictMapper.queryManyDictByKeys(dictCodeList, keys);
        Map<String, List<DictModel>> dictMap = new HashMap<>();
        for (DictModelMany dict : list) {
            List<DictModel> dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>());
            dictItemList.add(new DictModel(dict.getValue(), dict.getText()));
        }
        return dictMap;
    }

    @Override
    public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) {
        return sysDictMapper.queryTableDictTextByKeys(table, text, code, keys);
    }

    @Override
    public List<String> generateDictionaryInfo(String dictIds) {
        List<String> result = new ArrayList<>();
        List<String> dictIdList = Arrays.asList(dictIds.split(","));
        List<SysDict> dictList = this.list(new LambdaQueryWrapper<SysDict>()
                .in(SysDict::getId, dictIdList));
        List<SysDictItem> dictItemList = sysDictItemService.list(new LambdaQueryWrapper<SysDictItem>()
                .in(SysDictItem::getDictId, dictIdList)
                .orderByAsc(SysDictItem::getSortOrder));
        Map<String, List<SysDictItem>> dictItemMap = dictItemList.stream().collect(Collectors.groupingBy(SysDictItem::getDictId));

        String dicConstantPrefix = "public static final ";
        for (SysDict dict : dictList) {
            String dictCode = dict.getDictCode();
            String dictType = "";
            if (dict.getType().equals(0)) {
                dictType = "String ";
            } else if (dict.getType().equals(1)) {
                dictType = "Integer ";
            }
            String dictPrefix = dicConstantPrefix + dictType + dictCode.toUpperCase() + "_";
            if (dictItemMap.containsKey(dict.getId())) {
                List<SysDictItem> itemList = dictItemMap.get(dict.getId());
                for (SysDictItem item : itemList) {
                    // 拼接字典名称
                    String itemName = "";
                    String itemText = item.getItemText().replaceAll("[/\\\\()* ]", "");
                    if (itemText.length() == 1) {
                        itemName = ChinesePinyinUtil.getPingYin(itemText);
                    } else {
                        itemName = ChinesePinyinUtil.getPinYinHeadChar(itemText);
                    }
                    itemName = itemName.toUpperCase();
                    // 拼接字典值
                    String itemValue = "";
                    if (dict.getType().equals(0)) {
                        itemValue = "=\"" + item.getItemValue() + "\"; ";
                    } else if (dict.getType().equals(1)) {
                        itemValue = "=" + item.getItemValue() + "; ";
                    }
                    // 拼接注释
                    String dictAnnotation = "//" + item.getItemText();
                    result.add(dictPrefix + itemName + itemValue + dictAnnotation);
                }
            } else {
                result.add(dictPrefix);
            }
        }
        return result;
    }

    @Override
    public List<String> generateSql(String dictIds) {
        List<String> result = new ArrayList<>();
        List<String> dictIdList = Arrays.asList(dictIds.split(","));
        List<SysDict> dictList = this.list(new LambdaQueryWrapper<SysDict>()
                .in(SysDict::getId, dictIdList));
        List<SysDictItem> dictItemList = sysDictItemService.list(new LambdaQueryWrapper<SysDictItem>()
                .in(SysDictItem::getDictId, dictIdList)
                .orderByAsc(SysDictItem::getSortOrder));
        Map<String, List<SysDictItem>> dictItemMap = dictItemList.stream().collect(Collectors.groupingBy(SysDictItem::getDictId));

        String dictSqlPrefix = "INSERT INTO sys_dict ( id, dict_name, dict_code, description, del_flag, create_by, create_time, update_by, update_time, type ) VALUES ";
        String dictItemSqlPrefix = "INSERT INTO sys_dict_item ( id, dict_id, item_text, item_value, description, sort_order, STATUS, create_by, create_time, update_by, update_time ) VALUES";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (SysDict dict : dictList) {
            String dictSql = "('" + dict.getId() + "','"
                    + dict.getDictName() + "','"
                    + dict.getDictCode() + "',"
                    + (Strings.isBlank(dict.getDescription()) ? "NULL" : "'" + dict.getDescription() + "'") + ","
                    + dict.getDelFlag() + ",'"
                    + dict.getCreateBy() + "','"
                    + sdf.format(dict.getCreateTime()) + "',"
                    + (Strings.isBlank(dict.getUpdateBy()) ? "NULL" : "'" + dict.getUpdateBy() + "'") + ","
                    + (null == dict.getUpdateTime() ? "NULL" : "'" + sdf.format(dict.getUpdateTime()) + "'") + ","
                    + dict.getType() + ");";
            result.add(dictSqlPrefix + dictSql);
            if (dictItemMap.containsKey(dict.getId())) {
                List<SysDictItem> itemList = dictItemMap.get(dict.getId());
                for (SysDictItem item : itemList) {
                    String dictItemSql = "('" + item.getId() + "','"
                            + item.getDictId() + "','"
                            + item.getItemText() + "','"
                            + item.getItemValue() + "',"
                            + (Strings.isBlank(item.getDescription()) ? "NULL" : "'" + item.getDescription() + "'") + ","
                            + (null == item.getSortOrder() ? "NULL" : item.getSortOrder()) + ",'"
                            + item.getStatus() + "','"
                            + item.getCreateBy() + "','"
                            + sdf.format(item.getCreateTime()) + "',"
                            + (Strings.isBlank(item.getUpdateBy()) ? "NULL" : "'" + item.getUpdateBy() + "'") + ","
                            + (null == item.getUpdateTime() ? "NULL" : "'" + sdf.format(item.getUpdateTime()) + "'") + ");";
                    result.add(dictItemSqlPrefix + dictItemSql);
                }
            }
        }
        return result;
    }
}
